#include "../../Base/stdafx.h"
#include "TerrainFlat.h"
#include "../../Base/Light.h"
#include "../../Base/vertex.h"
#include "../../PhysX/PhysX.h"
#include "../../Effects/EffectLib.h"
#include "../../Effects/EffectShadow.h"

TerrainFlat::TerrainFlat(const D3DXVECTOR3& pos, float width, float length, const tstring& tex): 
m_Pos(pos), m_Width(width),m_Length(length)
{
	Init();
	HR(D3DX10CreateShaderResourceViewFromFile(GETDEVICE, tex.c_str(), NULL, NULL, &m_Texture, NULL));
	HR(D3DX10CreateShaderResourceViewFromFile(GETDEVICE, _T("./Textures/floor_normal.dds"), NULL, NULL, &m_NormalMap, NULL));
	HR(D3DX10CreateShaderResourceViewFromFile(GETDEVICE, _T("./Textures/WhiteTex.dds"), NULL, NULL, &m_SpecMap, NULL));
}

TerrainFlat::~TerrainFlat()
{
	if(m_VertexBufferPtr) m_VertexBufferPtr->Release();
	if(m_IndexBufferPtr) m_IndexBufferPtr->Release();
	m_NormalMap->Release();
	m_SpecMap->Release();
}

void TerrainFlat::Draw()
{
	//DXDevice::GetSingleton()->GetMatrixen(m_View, m_Proj);
	UINT stride = sizeof(Vertex);
	UINT offset = 0;
	//
	//effect->SetMatrixen(m_World, m_View, m_Proj);
	//effect->SetTexture(m_Texture);
	//effect->SetNormalTex(m_NormalMap);
	//effect->SetSpecularTex(m_SpecMap);
	//effect->SetTexScale(50, 50);

	GETDEVICE->IASetVertexBuffers(0, 1, &m_VertexBufferPtr, &stride, &offset);
	GETDEVICE->IASetIndexBuffer(m_IndexBufferPtr, DXGI_FORMAT_R32_UINT, 0);
	//if(step == 0 || step == 2)
		DXDevice::GetSingleton()->GetDevice()->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
	//else
	//	DXDevice::GetSingleton()->GetDevice()->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ);

	//D3D10_TECHNIQUE_DESC tech;
	//effect->GetTech(step)->GetDesc( &tech);
	//for(UINT t = 0; t < tech.Passes; ++t)
	//{
	//	effect->GetTech(step)->GetPassByIndex(t)->Apply(0);
		DXDevice::GetSingleton()->GetDevice()->DrawIndexed(6, 0, 0);
	//}
}

void TerrainFlat::Init()
{
	D3DXMatrixIdentity(&m_World);

	this->SetTranslate(m_Pos);

#pragma region VertexBuffer
	float width = m_Width / 2;
	float length = m_Length / 2;

	// Create vertex buffer
	vector<Vertex> v;

	// Fill in the top face vertex data.
	v.push_back(Vertex( D3DXVECTOR3(-width, 0.0f, -length), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0.0f, 1.0f), D3DXVECTOR3(1.0f, 0.0f, 0.0f)));
	v.push_back(Vertex( D3DXVECTOR3(-width, 0.0f,  length), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0.0f, 0.0f), D3DXVECTOR3(1.0f, 0.0f, 0.0f)));
	v.push_back(Vertex( D3DXVECTOR3(width, 0.0f,  length), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1.0f, 0.0f), D3DXVECTOR3(1.0f, 0.0f, 0.0f)));
	v.push_back(Vertex( D3DXVECTOR3(width, 0.0f, -length), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1.0f, 1.0f), D3DXVECTOR3(1.0f, 0.0f, 0.0f)));

	D3D10_BUFFER_DESC bd;
	bd.Usage = D3D10_USAGE_DEFAULT;
	bd.ByteWidth = sizeof( Vertex ) * 4;
	bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
	bd.MiscFlags = 0;
	D3D10_SUBRESOURCE_DATA InitData;
	InitData.pSysMem = &v[0];
	HR(DXDevice::GetSingleton()->GetDevice()->CreateBuffer( &bd, &InitData, &m_VertexBufferPtr ));
#pragma endregion
#pragma region IndexBuffer

	// Create the index buffer

	DWORD i[6];

	// Fill in the front face index data
	i[0] = 0; i[1] = 1; i[2] = 2;
	i[3] = 0; i[4] = 2; i[5] = 3;

	bd.Usage = D3D10_USAGE_DEFAULT;
	bd.ByteWidth = sizeof( DWORD ) * 6;        // 36 vertices needed for 12 triangles in a triangle list
	bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
	bd.CPUAccessFlags = 0;
	bd.MiscFlags = 0;
	InitData.pSysMem = i;
	HR(DXDevice::GetSingleton()->GetDevice()->CreateBuffer( &bd, &InitData, &m_IndexBufferPtr ));
#pragma endregion


	DXDevice::GetSingleton()->GetMatrixen(m_View, m_Proj);
	this->Translate(m_Pos);
	// NXActor
	NxActorDesc ActorDesc;
	D3DXComputeBoundingBox(&v[0].m_Pos, 4, sizeof(Vertex), &m_BoundingBox.minPt, &m_BoundingBox.maxPt);

	NxBoxShapeDesc BoxShapeDesc;
	D3DXVECTOR3 BBSize = m_BoundingBox.size();
	BoxShapeDesc.dimensions = NxVec3(BBSize.x / 2, BBSize.y/2, BBSize.z/2);
	BoxShapeDesc.mass = BBSize.x * BBSize.y * BBSize.z;
	ActorDesc.shapes.push_back(&BoxShapeDesc);
	NxMat34 mat;
	mat.setColumnMajor44(m_World);
	ActorDesc.globalPose = mat;
	ActorDesc.density = 10.0f;
	m_Actor = PhysX::GetSingleton()->GetScene()->createActor(ActorDesc);
}

const ID3D10ShaderResourceView* TerrainFlat::GetTexture() const
{
	return m_Texture;
}